home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Deutsche Edition 1
/
Deutsche Edition 1.iso
/
amok
/
041-050
/
amok49
/
oprof
/
txt
/
oprof.mod
< prev
next >
Wrap
Text File
|
1993-11-04
|
8KB
|
305 lines
(*
:Program. OProf.mod (OProf)
:Author. Volker Rudolph
:Address. Lettow-Vorbeck-Str. 11 / 6750 Kaiserslautern 26
:Phone. 06301/8566
:Version. 1.22
:Date. 4.11.90
:Copyright. Volker Rudolph (Shareware)
:Language. Oberon
:Translator. Oberon V1.17.1
:Imports. MicroTimer, Printf
:Contents. Laufzeit-Statistiken über Programme
*)
MODULE OProf;
IMPORT a:Arguments,as:ASCII,Break,NoGuru,st:Strings,p:Printf,io,l:Lists,s:SYSTEM,
ex:Expressions,te:Text,pr:ProfRunTime;
CONST
DEBUG = FALSE;
TYPE
CHARPtr = POINTER TO CHAR;
VAR
trace:INTEGER;
(* ------------------------------------------------------------------------- *)
PROCEDURE HashValue(VAR proc:pr.ProcName):INTEGER;
VAR
i:INTEGER;
hash:LONGINT;
BEGIN
i := 0;
hash := 0;
WHILE (i < pr.ProcNameLen) AND (proc[i] # as.nul) DO
(* $OvflChk- *)
hash := hash * 3 + ORD(proc[i]);
(* $OvflChk= *)
INC(i);
END; (* WHILE *)
IF hash = -32768 THEN
hash := 0;
ELSIF hash < 0 THEN
hash := -hash;
END; (* IF *)
RETURN SHORT(hash MOD pr.HashTableSize);
END HashValue;
(* -------------------------------------------------------------------------- *)
(* StackChk+ *)
PROCEDURE ExamineText;
VAR
node:l.NodePtr;
prev:l.NodePtr;
type:INTEGER;
str:pr.ProcName;
PROCEDURE ModifyImport;
VAR
node:l.NodePtr;
type:INTEGER;
str:pr.ProcName;
ok:BOOLEAN;
BEGIN
node := l.Head(te.ExList);
IF te.FindKeyWord({te.import},node,type) THEN
str := " prof:ProfRunTime,";
te.AddExpression(str,node,FALSE);
ELSIF te.FindKeyWord({te.module},node,type) THEN
WHILE (node # NIL) AND
( ((node IS te.MaxExNode) AND ~node(te.MaxExNode).semicolon) OR
((node IS te.MinExNode) AND ~node(te.MinExNode).semicolon)
) DO
ok := l.Next(node);
END; (* WHILE *)
IF node # NIL THEN
str := "\nIMPORT prof:ProfRunTime;\n\n";
te.AddExpression(str,node,TRUE);
END; (* IF *)
ELSE
pr.Assert(FALSE,"Format-error in sourcecode");
END; (* IF *)
END ModifyImport;
PROCEDURE AddEntryExit(scope:pr.ProcName;key:INTEGER):BOOLEAN;
VAR
found:INTEGER;
newScope:pr.ProcName;
function:BOOLEAN;
noBody:BOOLEAN;
ok:BOOLEAN;
ch:CHAR;
PROCEDURE SetNewScope;
VAR
exPtr:CHARPtr;
i,end:INTEGER;
ok:BOOLEAN;
BEGIN
ok := l.Next(node);
i := st.Length(newScope);
IF node^ IS te.MaxExNode THEN
exPtr := s.VAL(CHARPtr,node(te.MaxExNode).expression);
end := i + node^(te.MaxExNode).len;
ELSE
exPtr := s.ADR(node^(te.MinExNode).expression);
end := i + node^(te.MinExNode).len;
END; (* IF *)
IF i > 0 THEN
newScope[i] := '.';
INC(i);
END; (* IF *)
WHILE ex.IsASCII(exPtr^) AND (i < end) AND (i < pr.ProcNameLen-1) DO
newScope[i] := exPtr^;
INC(i);
INC(exPtr);
END; (* WHILE *)
newScope[i] := as.nul;
END SetNewScope;
PROCEDURE Prev(node:l.NodePtr):l.NodePtr;
VAR
ok:BOOLEAN;
BEGIN
ok := l.Previous(node);
RETURN node;
END Prev;
PROCEDURE GetLastChar(node:l.NodePtr):CHAR;
VAR
i:INTEGER;
p:ex.MaxExpressionPtr;
BEGIN
IF node IS te.MaxExNode THEN
p := node(te.MaxExNode).expression;
ELSE
p := s.ADR(node(te.MinExNode).expression);
END; (* IF *)
i := st.Length(p^)-1;
WHILE (i >= 0) AND (p[i] = ' ') DO
DEC(i);
END; (* WHILE *)
IF i >= 0 THEN
RETURN p[i];
ELSE
RETURN ' ';
END; (* IF *)
END GetLastChar;
BEGIN
IF DEBUG THEN
p.Printf1("AddEntryExit <%s>\n",s.ADR(scope));
END; (* IF *)
ok := l.Next(node);
newScope := scope;
function := FALSE;
noBody := TRUE;
WHILE te.FindKeyWord({te.end..te.halt},node,found) DO
CASE found OF
|te.begin:
IF (trace # 0) AND (key = te.module) THEN
p.SPrintf1(str,"prof.Trace := %ld;\n",trace);
te.AddExpression(str,node,TRUE);
ok := l.Next(node);
END; (* IF *)
p.SPrintf2(str,'prof.Entry("%s",%ld);\n',s.ADR(newScope),HashValue(newScope));
te.AddExpression(str,node,TRUE);
function := FALSE;
noBody := FALSE;
|te.end:
IF ((key = te.procedure) OR (key = te.module)) AND ~function AND ~noBody THEN
prev := Prev(node);
IF ((prev^ IS te.MaxExNode) AND ~prev^(te.MaxExNode).semicolon ) OR
((prev^ IS te.MinExNode) AND ~prev^(te.MinExNode).semicolon ) THEN
te.AddExpression(";\n",prev,TRUE);
END; (* IF *)
p.SPrintf2(str,'prof.Exit("%s",%ld);\n',s.ADR(newScope),HashValue(newScope));
te.AddExpression(str,Prev(node),TRUE);
END; (* IF *)
RETURN function;
|te.return:
p.SPrintf2(str,'prof.Exit("%s",%ld);\n',s.ADR(newScope),HashValue(newScope));
te.AddExpression(str,Prev(node),TRUE);
function := TRUE;
|te.halt:
te.AddExpression("prof.Halt;\n",Prev(node),TRUE);
|te.procedure,te.module:
ch := GetLastChar(node);
IF ch # '^' THEN
prev := Prev(node);
ch := GetLastChar(prev);
IF (ch # '=') AND (ch # ':') THEN
SetNewScope;
function := AddEntryExit(newScope,found);
noBody := TRUE;
newScope := scope;
END; (* IF *)
END; (* IF *)
|te.if..te.loop:
function := AddEntryExit(newScope,found);
newScope := scope;
|te.close:
IF ~noBody THEN
p.SPrintf2(str,'prof.Exit("%s",%ld);\n',s.ADR(newScope),HashValue(newScope));
te.AddExpression(str,Prev(node),TRUE);
function := TRUE;
END; (* IF *)
ELSE (* te.import *)
END; (* CASE *)
ok := l.Next(node);
END; (* WHILE *)
RETURN function;
END AddEntryExit;
BEGIN
p.SPrintf0(str,"(* OProf \xA91990 by Volker Rudolph *)\n\n");
te.AddExpression(str,NIL,FALSE);
ModifyImport;
node := l.Head(te.ExList);
str := "";
IF AddEntryExit(str,-1) THEN END;
END ExamineText;
(* StackChk= *)
(* -------------------------------------------------------------------------- *)
PROCEDURE WriteProf(name:ARRAY OF CHAR);
BEGIN
IF te.ReadText(name) THEN
ExamineText;
pr.Assert(te.WriteText(),"WRITE ERROR");
te.RemText;
ELSE
p.Printf0("DISK ERROR\n");
END; (* IF *)
END WriteProf;
(* -------------------------------------------------------------------------- *)
PROCEDURE DoArgs;
VAR
i:INTEGER;
num:INTEGER;
len:INTEGER;
arg:ex.String;
arg2:ex.String;
BEGIN
p.Printf0("OProf 1.22 \XA91990 by Volker Rudolph\n\n");
num := a.NumArgs();
IF num = 0 THEN
a.GetArg(0,arg);
p.Printf1("Usage:\n %s Files/...,TRACE/S,TRACE2/S\n",s.ADR(arg));
END; (* IF *)
i := 1;
WHILE i <= num DO
a.GetArg(i,arg);
st.Upper(arg);
IF arg = "TRACE" THEN
trace := 1;
ELSIF arg = "TRACE2" THEN
trace := 2;
ELSIF arg = "?" THEN
a.GetArg(0,arg);
p.Printf1("Usage:\n %s Files/...,TRACE/S,TRACE2/S\n",s.ADR(arg));
HALT(0);
END; (* IF *)
INC(i);
END; (* WHILE *)
i := 1;
WHILE i <= num DO
a.GetArg(i,arg);
arg2 := arg;
st.Upper(arg2);
IF (arg2 # "TRACE") AND (arg2 # "TRACE2") THEN
len := st.Length(arg);
IF (len > 3) AND (st.Occurs(arg2,".MOD") = len-4) THEN
arg[len-4] := as.nul;
WriteProf(arg);
ELSE
WriteProf(arg);
END; (* IF *)
END; (* IF *)
INC(i);
END; (* WHILE *)
p.Printf0("\nReady.\n");
END DoArgs;
(* -------------------------------------------------------------------------- *)
BEGIN
p.writeProc := io.WriteString;
pr.Quiet := TRUE;
trace := 0;
DoArgs;
END OProf.